/* component */
import BizTable from '@src/component/business/BizTable/BizTable'
import BaseListForNoData from '@src/component/common/BaseListForNoData/index.vue'
/* enum */
import ComponentNameEnum from '@model/enum/ComponentNameEnum'
/* model */
import { columns } from '@src/modules/account/roleService/component/RoleViewUserContent/model'
import LoginUser from '@model/entity/LoginUser/LoginUser'
/* hooks */
import { useRoleViewAuth } from '@src/modules/account/roleService/hooks'
import useLoading from '@src/modules/account/roleService/hooks/useLoading'
import { useStoreTableSelection } from '@src/modules/account/roleService/store/hooks'
/* vue */
import { ComponentInstance, defineComponent, PropType, Ref, ref, computed } from 'vue'
/* store */
/* scss */
import '@src/modules/account/roleService/component/RoleViewUserTable/index.scss'
/* util */
import { isOpenData } from '@src/util/platform'
import { isArray, isNotEmpty } from '@src/util/type'
import { strConcat as concat } from 'pub-bbx-utils'
import { openTabForUserView } from '@src/util/business/openTab'
import _ from 'lodash'
import { defaultTableData } from '@src/util/table'
/* vue */
import { CreateElement } from 'vue'
/* service */
import UserService from '@service/UserService'

type RoleViewUserTableColumnSlotDataType = { value: LoginUser }

export type RoleViewUserTableProps = {
  data: LoginUser[];
  isAllot: boolean;
  isEmpty: boolean;
}

export interface RoleViewUserTableSetupState {
  BizTableComponent: Ref<BizTable>;
}

export enum RoleViewUserTableEventEnum {
  Input = 'input',
  Select = 'select',
  ChangePageSize = 'changePageSize',
  ChangePageNum = 'changePageNum',
  Allot = 'allot',
  Delete = 'delete',
}

export type RoleViewUserTableEmitsOptions = {
  input: () => void;
}

export type RoleViewUserTableMethodsOptions = {
  clearSelection: () => void;
}

export type RoleViewUserTableInstance = ComponentInstance & RoleViewUserTableSetupState
export type RoleViewUserTableVM = RoleViewUserTableSetupState & RoleViewUserTableProps & ComponentInstance & RoleViewUserTableMethodsOptions

export default defineComponent({
  name: ComponentNameEnum.RoleViewUserTable,
  emits: [
    RoleViewUserTableEventEnum.Input,
    RoleViewUserTableEventEnum.ChangePageSize,
    RoleViewUserTableEventEnum.ChangePageNum,
    RoleViewUserTableEventEnum.Select,
    RoleViewUserTableEventEnum.Allot,
    RoleViewUserTableEventEnum.Delete,
  ],
  props: {
    data: {
      type: Array as PropType<LoginUser[]>,
      required: true,
      default: () => []
    },
    pageSize: {
      type: [Number, String],
      required: true,
      default: () => 10
    },
    pageNum: {
      type: [Number, String],
      required: true,
      default: () => 1
    },
    total: {
      type: Number as PropType<number>,
      required: true,
    },
    isAllot: {
      type: Boolean as PropType<boolean>,
      default: false
    },
    isEmpty: {
      type: Boolean as PropType<boolean>,
      default: false
    }
  },
  setup(props: RoleViewUserTableProps, { slots, emit }) {
    
    const { tableSelection } = useStoreTableSelection()
    const { canRemoveUser, canViewUser } = useRoleViewAuth()
    const { loading:pageLoading } = useLoading()
    const isTableLoading = computed(() => {
      
      if (pageLoading.value) {
        return false
      }
      
      return !props.isEmpty && !pageLoading.value
    })
    
    const BizTableComponent: Ref<BizTable | null> = ref(null)
    
    function onPaginationPageNumChangedHandler(pageNum: number) {
      emit(RoleViewUserTableEventEnum.ChangePageNum, pageNum)
    }
    
    function onPaginationPageSizeChangedHandler(pageSize: number) {
      emit(RoleViewUserTableEventEnum.ChangePageSize, pageSize)
    }
    
    function onChangeSelectionHandler(selection: LoginUser[]) {
      
      let newSelection: LoginUser[] = []
      
      let tv: LoginUser[] = []
      
      tv = tableSelection.value.filter(selection =>
        props.data.every(user => user.userId !== selection.userId)
      )
      
      tv = _.uniqWith([...tv, ...selection], _.isEqual)
      
      newSelection = tv
      
      emit(RoleViewUserTableEventEnum.Select, newSelection)
    }
    
    function onAllotRoleClickHandler(user: LoginUser) {
      emit(RoleViewUserTableEventEnum.Allot, user)
    }
    
    function onDeleteUserButtonClickHandler(user: LoginUser) {
      emit(RoleViewUserTableEventEnum.Delete, user)
    }
    
    function clearSelection() {
      BizTableComponent.value && BizTableComponent.value.clearSelection()
    }
    
    return {
      canRemoveUser,
      canViewUser,
      onPaginationPageNumChangedHandler,
      onPaginationPageSizeChangedHandler,
      onChangeSelectionHandler,
      clearSelection,
      onAllotRoleClickHandler,
      onDeleteUserButtonClickHandler,
      BizTableComponent,
      isTableLoading
    }
    
  },
  methods: {
    renderTableScopedSlot(h: CreateElement) {
      return {
        displayName: (data: RoleViewUserTableColumnSlotDataType) => this.renderTableScopedSlotDisplayName(h, data),
        department: (data: RoleViewUserTableColumnSlotDataType) => this.renderTableScopedSlotDepartments(h, data),
        phone: (data: RoleViewUserTableColumnSlotDataType) => this.renderTableScopedSlotPhone(h, data),
        qualificationNames: (data: RoleViewUserTableColumnSlotDataType) => this.renderTableScopedSlotQualificationNames(h, data),
        operator: (data: RoleViewUserTableColumnSlotDataType) => this.renderTableScopedSlotOperator(h, data),
      }
    },
    renderTableScopedSlotDisplayName(h: CreateElement, data: RoleViewUserTableColumnSlotDataType) {
      
      const isSuperAdmin = UserService.isSuperAdmin(data.value)
      
      const labelList = data.value?.labelList || []
      const isLabelListNotEmpty = isArray(labelList) && isNotEmpty(labelList)
      
      const onUserNameClickHandler = () => {
        if (this.canViewUser) {
          openTabForUserView(data.value?.userId)
        }
      }
      
      return (
        <div class="role-view-user-table_row">
          
          <div 
            class={[this.canViewUser ? 'view-detail-btn' : 'view-detail-btn-disabled']} 
            onClick={onUserNameClickHandler}
          >
            {isOpenData ? (
              <open-data type="userName" openid={data.value.staffId}>
              </open-data>
            ) : (
              data.value.displayName
            )}
          </div>
          
          {data.value.isTeamLeader && (
            <user-label text={this.$t('common.base.executiveDirector')} />
          )}
          
          {isSuperAdmin && (
            <user-label text={this.$t('common.label.admin')} />
          )}
          
          {isLabelListNotEmpty && (
            <div>
              {labelList.map((label) => {
                return <user-label is-sample text={label.labelName} />
              })}
            </div>
          )}
          
        </div>
      )
    },
    renderTableScopedSlotDepartments(h: CreateElement, data: RoleViewUserTableColumnSlotDataType) {
      
      const tagList = (data.value.roles && data.value.tagList) || []
      
      const tagNames = tagList.map(tag => tag?.tagName || '')
      
      return concat(tagNames)
    },
    renderTableScopedSlotPhone(h: CreateElement, data: RoleViewUserTableColumnSlotDataType) {
      return data.value.cellPhone || ''
    },
    renderTableScopedSlotOperator(h: CreateElement, data: RoleViewUserTableColumnSlotDataType) {
      
      if (this.isAllot) {
        return this.renderTableScopedSlotOperatorAllot(h, data)
      }
      
      // 是否为超级管理员
      const isSuperAdmin = UserService.isSuperAdmin(data.value)
      
      if (!this.isAllot && !isSuperAdmin && this.canRemoveUser ) {
        return this.renderTableScopedSlotOperatorRemove(h, data)
      }
      
    },
    renderTableScopedSlotOperatorRemove(h: CreateElement, data: RoleViewUserTableColumnSlotDataType) {
      return (
        // <el-button
        //   type="text"
        //   onClick={() => this.onDeleteUserButtonClickHandler(data.value)}
        // >
        //   移除
        // </el-button>
        <el-link type="danger" underline={false} onClick={() => this.onDeleteUserButtonClickHandler(data.value)}>{this.$t('common.base.remove')}</el-link>
      )
    },
    renderTableScopedSlotOperatorAllot(h: CreateElement, data: RoleViewUserTableColumnSlotDataType) {
      return (
        <el-button
          type="text"
          onClick={() => this.onAllotRoleClickHandler(data.value)}
        >
          {this.$t('common.base.allotRole')}
        </el-button>
      )
    },
    renderTableScopedSlotQualificationNames(h: CreateElement, data: RoleViewUserTableColumnSlotDataType){
      const { qualificationNames } = data.value
      return qualificationNames && qualificationNames.join('，')
    }
  },
  render(h) {
    return (
      <div class={ComponentNameEnum.RoleViewUserTable}>
        
        <biz-table
          ref='BizTableComponent'
          data={this.data}
          columns={columns}
          onChangeSelection={this.onChangeSelectionHandler}
          scopedSlots={this.renderTableScopedSlot(h)}
          loading={this.isTableLoading}
        > 
        </biz-table>
        
        <div class='role-view-user-table__pagination'>
          <el-pagination
            background
            hide-on-single-page
            pageSizes={defaultTableData.defaultPageSizes}
            onCurrent-change={this.onPaginationPageNumChangedHandler}
            onSize-change={this.onPaginationPageSizeChangedHandler}
            pageSize={this.pageSize}
            currentPage={this.pageNum}
            layout={defaultTableData.defaultLayout}
            total={this.total}
            >
            </el-pagination>
          </div>
        
      </div>
    ) as any
  },
  components: {
    'user-label': {
      props: {
        isSample: {
          type: Boolean,
          default: false
        },
        text: {
          type: String,
          default: ''
        }
      },
      render() {
        
        const classNames = [
          'role-view-super-admin-label',
          this.isSample ? 'role-view-super-admin-label__auto' : ''
        ]
        
        return (
          <span class={classNames}>
            { this.text }
          </span>
        )
      }
    }
  }
}) as any
